#ifndef __CLI_PARSE__LEVEL_H__
#define __CLI_PARSE__LEVEL_H__

#include "structs.h"

#include "../../Epsilon/strings.h"
#include "../../Epsilon/file.h"

namespace cli_parse {
  class EntryPoint;
};

namespace Underlight
{
  class Sector;
  class Room;

  class Level;
  extern Level* lvl;

  Level* GetLevel         (int num);
  bool   IsLevelLoaded    (int num);

  class FileLevel
  {
  public:
    LevelHeader _header;
    LevelData   _data;
  };

  class Level //: public Epsilon::Node
  {
  public:
    Level (void)
    {
      id = 0;
    }

    virtual ~Level (void)
    {
      rooms.clear        ();
      entry_points.clear ();
    }

    Room* RoomFromSector (int id) const;

  public:
    bool Load (void* data, FileLevel& level);

    /// Mutators
    void AddRoom (Room* room)
    {
      rooms.push_back (room);
    }

    void AddTexture (short tex_id)
    {
      if (! IsTextureLoaded (tex_id))
        textures.push_back (tex_id);
    }

    void AddFlatTex (short flat_id)
    {
      if (! IsFlatTexLoaded (flat_id))
        flats.push_back (flat_id);
    }

    void AddSector (Sector* sector);

    /// Selectors
    Room*   GetRoom       (int id);
    Sector* GetSector     (int id);

    /* Return NULL if no sector is found and must_exist is true. */
    Sector* FindSector    ( float   x,
                            float   y,
                            Sector* oldsector,
                            bool    set_anywhere,
                            bool    must_exist = false );

    bool  IsTextureLoaded (short id);
    bool  IsFlatTexLoaded (short id);

    size_t MemSize (void);

  //private:
    /* TODO: Using vectors saves memory, but requires O (n) search time,
               Underlight makes heavy use of reference by id... but it
                 is capable of dereferncing by ID in O (1).

             These data structures may be contributing to CPU-bound
               performance issues!
    */
    std::vector<short>   textures;  ///< List of all texture IDs used
    std::vector<short>   flats;     ///< List of all flat IDs used

    std::vector<Room*>   rooms;
    std::vector<Sector*> sectors; ///< NOTE: Sectors are owned by rooms...

    std::vector<cli_parse::EntryPoint*>
                         entry_points;

    int  id;
    char name [LEVEL_NAME_SIZE];

    FileLevel _lvl;
  };

  
  class File {
  public:
    File (const TCHAR* name)
    {
      _file = NULL;

      if (name != NULL) {
        _tcsncpy (file_name, name, MAX_PATH);
      }

      num_levels = 0;
    }

    virtual ~File (void)
    {
      if (_file != NULL) {
        //fclose (_file);

        delete _file;
        _file = NULL;
      }
    }

    bool Load (int num);

  protected:
    int num_levels;

  private:
    TCHAR file_name [MAX_PATH + 1];
    int   size;

    eFile* _file;

    FileHeader _header;

    std::vector<FileLevel> _levels;
  };
};


#endif /* __CLI_PARSE__LEVEL_H__ */
